package com.caifu.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.caifu.bean.Result;
import com.caifu.bean.ResultUtil;
import com.caifu.pojo.SysLog;
import com.caifu.pojo.SysMenu;
import com.caifu.pojo.SysUser;
import com.caifu.service.SysLogService;
import com.caifu.service.SysMenuService;
import com.caifu.service.SysUserService;
import com.caifu.util.DesUtil;
import com.caifu.util.ShiroUtil;
import com.caifu.util.Util;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Auther: szt
 * @Date: 2020/11/24 19:57
 * @Description:
 */
@Controller
@ApiIgnore
@RequestMapping("/gc")
public class GcLoginController extends AbstractController{

    final static Logger logger = LoggerFactory.getLogger(GcLoginController.class);

    @Autowired
    private SysMenuService menuService;
    @Autowired
    private SysUserService userService;
    @Autowired
    private SysLogService logService;

    //跳到登录页
    //http://192.168.180:9999/ATPension/gc
    @RequestMapping(value = {"","/","/login","login"})
    public String login(ModelMap model, Integer type){
        if(type==null){
            type=0;
        }
        model.put("type",type);
        return "view/gcSys/login";
    }

    //登陆
    @RequestMapping("/authentication")
    @ResponseBody
    public JSONObject authentication(SysUser user) throws Exception {
        SysUser oldUser = new SysUser();
        JSONObject obj = new JSONObject();
        int code = 200;
        String msg = "登陆成功！";
        Subject subject = SecurityUtils.getSubject();
        try {
            //判断当日连续失败登陆次数是否超过5次
//            int count = errorService.count(new QueryWrapper<SysLoginError>()
//                    .eq("day", Util.currentDate()).eq("login_name", user.getLoginName()));
//            if(count>=5){
//                msg = "连续登陆失败次数超过5次, 账户已锁";
//                code = 103;
//            }else{
            if(1==1){
                oldUser = userService.getUserByLoginName(user.getLoginName(),"2");
                if(oldUser==null){
                    int closeCount = userService.count(new QueryWrapper<SysUser>().eq("login_name",user.getLoginName()).ne("status","1"));
                    if(closeCount>0){
                        msg = "该账户已经被停用, 请联系管理员";
                        code = 104;
                    }else{
                        msg = "用户名不存在, 请重新输入！";
                        code = 104;
                    }
                }else{
                    if(oldUser.getPostType().equals("1")){
                        msg = "非供餐机构管理员，请用供餐机构管理员登陆！";
                        code = 104;
                    }
                    if (!subject.isAuthenticated()){
                        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                                user.getLoginName(),
                                user.getPassword()
                        );
                        subject.login(usernamePasswordToken);
                        //subject.getSession().setTimeout(43200000);//12个小时
                        subject.getSession().setTimeout(1800000);
                        user.setCurrentPensionNo("100");
                        subject.getSession().setAttribute("user",user);
                        userService.updateLoginTime(user.getLoginName());
                        userService.loginSuccess(oldUser.getUserNo(),user.getLoginName());
                    }
                }
            }
        } catch (AuthenticationException e) {
            code = 101;
            msg = "密码错误, 请重新输入！";
            if(oldUser!=null){
                userService.loginError(oldUser.getUserNo(), oldUser.getLoginName());
            }
        } catch (AuthorizationException e) {
            msg = "没有权限";
            code = 102;
        } catch (Exception e) {
            e.printStackTrace();
        }
        obj.put("code",code);
        obj.put("msg",msg);
        return obj;
    }

    @RequestMapping("/index")
    public String index(ModelMap model) throws Exception{
        if(getUser() != null) {
            //查询板块列表（排除平台管理）
            List<Map<String, Object>> appList = menuService.listMaps(new QueryWrapper<SysMenu>().select("name", "menu_no").eq("TYPE", "0").orderByAsc("sort"));
            appList.forEach(obj -> {
                obj.put("menu_no", DesUtil.encrypt(obj.get("menu_no") + ""));
            });
            //获取优先显示板块代码
            int initMenu = menuService.getFirstShowMenu(getUserNo());

            SysUser user = getUser();
            SysUser tmpUser = userService.getById(getUserNo());
            if (tmpUser == null) {
                throw new Exception("SysUser查询失败，userNo=" + getUserNo());
            }
            model.put("pwdFlag", tmpUser.getPasswordEditFlag());
            model.put("userName", user.getUserName());
            model.put("userPhoto", user.getUserPhoto());
            model.put("userNo", DesUtil.encrypt(getUserNo() + ""));
            model.put("appList", appList);
            model.put("initMenu", DesUtil.encrypt(initMenu + ""));
            return "view/gcSys/index";
        }else{
            return "view/gcSys/login";
        }
    }

    @RequestMapping("/welcome")
    public String welcome(){
        return "view/sys/welcome";
    }

    //获取菜单
    //192.168.1.180:9999/ATPension/getMenuByUser?menuNo=B9FA51FEA72196F1
    @RequestMapping("/getMenuByUser")
    @ResponseBody
    public Result getMenuByUser(String menuNo) throws Exception{
        Object obj;
        try{
            String userNo = getUser().getUserNo()+"";
            //平台管理 服务中心 养老机构 数据看板
            obj = menuService.getUserMenu(Integer.parseInt(userNo),DesUtil.decrypt(menuNo));

            return ResultUtil.success(200,String.valueOf(getUserNo()),obj);
        }catch (Exception e){
            e.printStackTrace();
            logger.error("获取用单失败！");
            throw new Exception("获取用单失败！");
        }
    }

    //重设密码
    //192.168.1.180:9999/ATPension/resetPsw
    @RequestMapping("/resetPsw")
    public String resetPwd(String phone, ModelMap model){
        model.put("phone", phone);
        return "view/sys/resetPsw";
    }

    //重设密码
    //192.168.1.180:9999/ATPension/resetPswSuc
    @RequestMapping("/resetPswSuc")
    public String resetPswSuc(){
        return "view/sys/resetPswSuc";
    }

    //身份验证
    //192.168.1.180:9999/ATPension/identity
    @RequestMapping("/identity")
    public String identity(ModelMap model){
        return "view/sys/identity";
    }

    //退出登录
    @RequestMapping("/outLogin")
    public String outLogin() throws Exception{
        SysUser oldUser = new SysUser();

        try {
            oldUser = userService.getById(getUserNo());

            //日志记录  sys 组织架构模块  sys-206 操作员退出
            SysLog log = new SysLog(getUserNo(), "1","sys", "sys-206", "1", oldUser.getLoginName()+"登陆退出成功！", new Date());
            logService.save(log);
            ShiroUtil.logout();
            return "redirect:login";
        } catch (Exception e) {
            e.printStackTrace();
            //日志记录  sys 组织架构模块  sys-206 操作员退出
            SysLog log = new SysLog(getUserNo(), "1","sys", "sys-206", "9", oldUser.getLoginName()+"登陆退出失败！", new Date());
            logService.save(log);
            throw new Exception("登陆退出失败！");
        }
    }

    //修改密码
    @RequestMapping("/changePassword")
    @ResponseBody
    public Result changePassword(String phone, String newPassword){
        SysUser user = new SysUser();
        try{
            //重置密码
            user = userService.getOne(new QueryWrapper<SysUser>().eq("phone", phone).eq("post_type","1"));

            String salt = Util.getStringRandom(20);
            String password = ShiroUtil.sha256(newPassword, salt);

            user.setPaw(newPassword);
            user.setPasswordEditFlag("1");
            user.setPassword(password);
            userService.updateById(user);
            //日志记录  sys 组织架构模块  sys-209 修改密码
            SysLog log = new SysLog(user.getUserNo(), "1","sys", "sys-209", "1", user.getLoginName()+"修改用户密码成功！", new Date());
            logService.save(log);
            return ResultUtil.success(200, "密码修改成功！",userService.update(new UpdateWrapper<SysUser>().lambda().set(SysUser::getPaw,newPassword).set(SysUser::getSalt,salt).set(SysUser::getPassword,password).eq(SysUser::getUserNo,user.getUserNo())));
        }catch (Exception e){
            e.printStackTrace();
            logger.error("密码修改失败！");
            //日志记录  sys 组织架构模块  sys-302 修改密码
            SysLog log = new SysLog(user.getUserNo(), "1","sys", "sys-209", "9", user.getLoginName()+"修改用户密码失败！", new Date());
            logService.save(log);
            return ResultUtil.error(199,"密码修改失败！");
        }
    }
}
